/***************************************************************************
 *   Copyright (C) 2009 by umbacos@gmail.com                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "udm-common.h"

extern char* dcgi;
extern char* droo;
extern char* dbin;
extern char* dwww;
extern char* dufb;
extern char* ddnl;
extern char* dtrk;
extern char* filter;
extern char* fcnf;
extern char* pidfile;
extern char* wget;
extern char* ctor;

char* path;

#ifdef DEBUG
void mylog ( char * a, char * b ) {
	FILE * fd;
	fd = fopen ( LOGFILE, "a" );
	fprintf ( fd, "%s%s\n", ( a == NULL ? "(NULL)" : a ), ( b == NULL ? "(NULL)" : b ) );
	fclose ( fd );
}

char * ltos(long long l) {
	char s[20];
	sprintf(s, "%lld", l);
	return strdup(s);
}
#endif

void * xmalloc ( size_t size ) {
	void *buf;

	if ( ( buf = malloc ( size ) ) == NULL ) {
		printf ( "Memory Allocation Failure" );
		return NULL;
	}

	memset ( buf, 0, size );

	return buf;
}

int filter_select ( struct dirent *entry ) {
	if ( ( strcmp ( entry->d_name, "." ) == 0 ) || ( strcmp ( entry->d_name, ".." ) == 0 ) )
		return ( FALSE );
	else if ( strlen ( filter ) == 0 )
		return ( TRUE );
	else if ( strstr ( entry->d_name, filter ) != NULL )
		return ( TRUE );
	else
		return ( FALSE );
}

void mandatory ( char * name, char * value ) {
	if ( ! value ) {
		fprintf ( stderr, "zarvland: value required for %s option\n", name );
		exit ( 1 );
	}
}

char * add_slash (char * in) {
	char * out;
	int len;

	len = strlen(in);
	if ( in[len-1] == '/') return strdup ( in );
	out = xmalloc ( len + 1 );
	strcat ( strcpy (out, in), "/" );
	return out;
}

void dump_cnf() {

	FILE * fo;

#ifdef DEBUG
	mylog ( "Dumping config to ", TMP_CNF );
#endif
	fo = fopen ( TMP_CNF, "w" );

	if ( fo == ( FILE* ) 0 ) {
		syslog ( LOG_CRIT, "%s - %m", fcnf );
		printf ( "Cannot write temporary configuration file %s\n", fcnf );
		return;
	}

	fprintf ( fo, "droo=%s\n", droo );
	fprintf ( fo, "dbin=%s\n", dbin );
	fprintf ( fo, "wget=%s\n", wget );
	fprintf ( fo, "ctor=%s\n", ctor );
	fprintf ( fo, "dwww=%s\n", dwww );
	fprintf ( fo, "dufb=%s\n", dufb );
	fprintf ( fo, "dnldir=%s\n", ddnl );
	fprintf ( fo, "pidfile=%s\n", pidfile );
	fprintf ( fo, "path=%s\n", path );
	fclose ( fo );

	mkdir ( ddnl, 644 );
}

void get_directories ( char * file ) {

	struct stat buf;
	char * entry;
	char * outry;
	FILE * fp;
	char line[1000];
	char* cp;
	char* cp2;
	char* name;
	char* value;
	int r;
	int is_daemon;

#ifdef DEBUG
	mylog ( "***********************\n", "get_directories start" );
#endif
	r = chdir ( dirname ( file ) );
	if ( stat ( "udmd" , &buf ) == 0) 	is_daemon = 1;
	else					is_daemon = 0;

#ifdef DEBUG
	mylog ( "is_daemon=", ltos((long long)is_daemon) );
#endif
	if ( is_daemon ) { /* we are udmd */

		r = chdir ( ".." );
		entry = getcwd ( NULL, 0 );

		/* defaults */
		droo = xmalloc ( strlen ( entry ) + 1 );
		strcat ( strcpy ( droo, entry ), "/" );
#ifdef DEBUG
	mylog ( "WE ARE UDMD:\nstart defaults:", "" );
	mylog ( "droo=", droo );
#endif

		dbin = xmalloc ( strlen ( droo ) + strlen ( D_BIN ) + 1 );
		strcat ( strcpy ( dbin, droo ), D_BIN );
#ifdef DEBUG
	mylog ( "dbin=", dbin );
#endif

		wget = xmalloc ( strlen ( dbin ) + strlen ( "wget" ) + 1 );
		strcat ( strcpy ( wget, dbin ), "wget" );
		if ( stat ( wget, &buf ) != 0 ) strcpy ( wget, "wget" );
#ifdef DEBUG
	mylog ( "wget=", wget );
#endif

		ctor = xmalloc ( strlen ( dbin ) + strlen ( "ctorrent" ) + 1 );
		strcat ( strcpy ( ctor, dbin ), "ctorrent" );
		if ( stat ( ctor, &buf ) != 0 ) strcpy ( ctor, "ctorrent" );
#ifdef DEBUG
	mylog ( "ctor=", ctor );
#endif

		dwww = xmalloc ( strlen ( droo ) + strlen ( D_WWW ) + 1 );
		strcat ( strcpy ( dwww, droo ), D_WWW );
#ifdef DEBUG
	mylog ( "dwww=", dwww );
#endif

		dufb = xmalloc ( strlen ( droo ) + strlen ( D_UFB ) + 1 );
		strcat ( strcpy ( dufb, droo ), D_UFB );
#ifdef DEBUG
	mylog ( "dufb=", dufb );
#endif

		dtrk = xmalloc ( strlen ( dwww ) + strlen ( D_TRK ) + 1 );
		strcat ( strcpy ( dtrk, dwww ), D_TRK );
#ifdef DEBUG
	mylog ( "dtrk=", dtrk );
#endif

		dcgi = xmalloc ( strlen ( dwww ) + strlen ( D_CGI ) + 1 );
		strcat ( strcpy ( dcgi, dwww ), D_CGI );
#ifdef DEBUG
	mylog ( "dcgi=", dcgi );
#endif

		ddnl = xmalloc ( strlen ( dwww ) + strlen ( D_DNL ) + 1 );
		strcat ( strcpy ( ddnl, dwww ), D_DNL );
#ifdef DEBUG
	mylog ( "ddnl=", ddnl );
#endif

		pidfile = xmalloc ( strlen ( dbin ) + strlen ( PID_FILE ) );
		strcat ( strcpy ( pidfile, dbin ), PID_FILE );
#ifdef DEBUG
	mylog ( "pidfile=", pidfile );
#endif

		fcnf = xmalloc ( strlen ( droo ) + strlen ( F_CNF ) + 1 );
		strcat ( strcpy ( fcnf, droo ), F_CNF );
#ifdef DEBUG
	mylog ( "fcnf=", fcnf );
#endif

#ifdef DEBUG
	mylog ( "end defaults", "" );
#endif
		fp = fopen ( fcnf, "r" );
		if ( fp == ( FILE* ) 0 ) {
			printf ( "CRIRICAL ERROR: opening %s", F_CNF );
			syslog ( LOG_CRIT, "%s - %m", fcnf );
			perror ( fcnf );
			exit ( 1 );
		}
#ifdef DEBUG
		mylog ( "read cnf file ", F_CNF );
#endif
	} else { /* we are in a CGI */
		fp = fopen ( TMP_CNF, "r" );
		if ( fp == ( FILE* ) 0 )
			send_message ( "CRITICAL ERROR: opening temporary ", TMP_CNF );
#ifdef DEBUG
		mylog ( "read cnf file ", TMP_CNF );
#endif
	}

	while ( fgets ( line, sizeof ( line ), fp ) != ( char* ) 0 ) {
		/* comments */
		if ( ( cp = strchr ( line, '#' ) ) != ( char* ) 0 ) * cp = '\0';
		/* leading whitespace. */
		cp = line;
		cp += strspn ( cp, " \t\012\015" );

		/* Split line into words. */
		while ( *cp != '\0' ) {
			/* Find next whitespace. */
			cp2 = cp + strcspn ( cp, " \t\012\015" );
			/* Insert EOS and advance next-word pointer. */

			while ( *cp2 == ' ' || *cp2 == '\t' || *cp2 == '\012' || *cp2 == '\015' )
				*cp2++ = '\0';

			/* Split into name and value. */
			name = cp;
			value = strchr ( name, '=' );
			if ( value != ( char* ) 0 ) *value++ = '\0';

			/* Interpret. */
			if ( strcmp ( name, "dnldir" ) == 0 ) {
				mandatory ( name, value );
				ddnl = strdup ( value );
			} else if ( strcmp ( name, "droo" ) == 0 ) {
				mandatory ( name, value );
				droo = strdup ( value );
			} else if ( strcmp ( name, "dbin" ) == 0 ) {
				mandatory ( name, value );
				dbin = strdup ( value );
			} else if ( strcmp ( name, "dwww" ) == 0 ) {
				mandatory ( name, value );
				dwww = add_slash ( value );
				dtrk = xmalloc ( strlen ( dwww ) + strlen ( D_TRK ) + 1 ); strcat ( strcpy ( dtrk, dwww ), D_TRK );
				dcgi = xmalloc ( strlen ( dwww ) + strlen ( D_CGI ) + 1 ); strcat ( strcpy ( dcgi, dwww ), D_CGI );
			} else if ( strcmp ( name, "dufb" ) == 0 ) {
				mandatory ( name, value );
				dufb = add_slash ( value );
			} else if ( strcmp ( name, "pidfile" ) == 0 ) {
				mandatory ( name, value );
				pidfile = strdup ( value );
			} else if ( strcmp ( name, "wget" ) == 0 ) {
				mandatory ( name, value );
				if ( strlen ( value ) ) wget = strdup ( value );
			} else if ( strcmp ( name, "ctor" ) == 0 ) {
				mandatory ( name, value );
				if ( strlen ( value ) ) ctor = strdup ( value );
			} else if ( strcmp ( name, "path" ) == 0 ) {
				mandatory ( name, value );
				path = strdup ( value );
			} else {
				fprintf ( stderr, "Unknown config option '%s'\n", name );
				exit ( 1 );
			}

			/* Advance to next word. */
			cp = cp2;
			cp += strspn ( cp, " \t\012\015" );
		}
	}

	fclose ( fp );
	if ( is_daemon ) dump_cnf();

#ifdef DEBUG
	mylog ( "*****************", "" );
	mylog ( "* CONFIGURATION *", "" );
	mylog ( "*****************", "" );
	mylog ( "path=", path );
	mylog ( "droo=", droo );
	mylog ( "dbin=", dbin );
	mylog ( "wget=", wget );
	mylog ( "ctor=", ctor );
	mylog ( "dwww=", dwww );
	mylog ( "dufb=", dufb );
	mylog ( "dtrk=", dtrk );
	mylog ( "dcgi=", dcgi );
	mylog ( "dnldir=", ddnl );
	mylog ( "pidfile=", pidfile );
	mylog ( "", "" );
	mylog ( "*****************", "" );
	mylog ( "*****************", "" );
#endif
	strcat ( strcat ( strcat ( strcat ( strcpy ( line, path ), ":" ), dbin ), ":" ), getenv ( "PATH" ) );
#ifdef DEBUG
	mylog ( "set PATH=", line );
#endif
	setenv ( "PATH", line, 1 );
#ifdef DEBUG
	mylog ( "get_directories end\n", "***********************" );
#endif
}

char* pipe_cmd ( char * cmd ) {

	FILE *fp;
	int status;
	char procs[1000];
	char out[10000];
	char ccmd[1000];

	out[0] = '\0';
	procs[0] = '\0';

	sprintf ( ccmd, "%s 2>&1", cmd);

	if ( ( fp = popen ( ccmd, "r" ) ) == NULL )
		send_message ( "Unable to start subshell: ", ccmd );

	while ( fgets ( procs, 1000, fp ) )
		strncat ( out, procs, 10000 - strlen ( out ) );

	if ( pclose ( fp ) == -1 ) send_message ( "Cannot close pipe to shell:", ccmd );

	return strdup ( out );
}
